<template>
	<page-meta :page-style="'overflow:' + (calendarVisible ? 'hidden' : 'visible')"></page-meta>
	<view class="page-container bg-grey" v-if="ticketData.id">
		<up-navbar v-bind="navbarProps" @leftClick="pageBack"></up-navbar>
		<ImageSwiper :detail_urls="ticketData.detail_urls" />
		<view
			class="tabs"
			:style="{ top: tabShow ? commonStore.navbarHeight + commonStore.statusBarHeight + 'px' : 0 }"
			v-if="tabShow"
		>
			<view
				v-for="item in tabList"
				:key="item.id"
				class="item"
				:class="{ checked: currentTabId === item.id }"
				@click="handleTabClick(item.id)"
			>
				{{ item.text }}
			</view>
		</view>

		<TicketInfo
			:display_name="ticketData.display_name"
			:sale_tips="ticketData.sale_tips"
			:intro="ticketData.intro"
			:score_in_cent="ticketData.score_in_cent"
			:prices="ticketData.prices"
			:price_in_cent="checkedPriceInfo.price_in_cent"
		/>

		<template v-if="ticketData.sale_type === 10">
			<view class="card prices" id="product-order">
				<view class="card-title">游玩日期</view>
				<PriceList
					:id="id"
					:prices="ticketData.prices"
					page_type="ticket"
					:latest_sale_date="ticketData.latest_sale_date"
					@price-change="handlePriceChange"
					@calendar-visible="handleCalendarVisible"
				/>
			</view>
		</template>

		<view class="card resort" :style="{ backgroundImage: `url(${imgBaseUrl}resort-bg.png)` }">
			<Resort :resort="ticketData.resort" />
		</view>

		<view class="card" id="buy-notice">
			<NoticeCard :sale_tips="ticketData.sale_tips" :booking_tips="ticketData.booking_tips" />
		</view>

		<view id="product-intro"></view>

		<Description :description="ticketData.description" />

		<Store :store="ticketData.store" />

		<PriceDescription />

		<view class="bottom">
			<navigator class="icons" url="/pages/home/index" open-type="switchTab" hover-class="none">
				<image class="home-icon" :src="`${imgBaseUrl}home-icon.png`" />
				<text class="text">首页</text>
			</navigator>
			<view class="btn" :class="{ disabled: !hasPrices }" @click="submit">
				{{ hasPrices ? "立即预定" : "暂不可预定" }}
			</view>
		</view>
	</view>
</template>

<script setup>
import { onLoad, onPageScroll, onReachBottom } from "@dcloudio/uni-app"
import { ref, reactive, computed, getCurrentInstance, nextTick } from "vue"
import { $getTicketDetail } from "@/api/ticket"
import { pageBack } from "@/utils/page-redirect"
import { needLogin } from "@/utils/users"
import { getIdBYScene } from "@/utils/tools"
import useCommonStore from "@/store/common"
import ImageSwiper from "../components/image-swiper.vue"
import TicketInfo from "../components/ticket-info.vue"
import PriceList from "../components/price-list.vue"
import Resort from "../components/resort.vue"
import NoticeCard from "../components/notice-card.vue"
import Description from "../components/description.vue"
import Store from "../components/store.vue"
import PriceDescription from "../components/price-description.vue"
const imgBaseUrl = inject("imgBaseUrl")
let scroll_top = 0
let timer = null

const id = ref("")
const currentTabId = ref("")
const tabShow = ref(false)
const isTabChange = ref(false)
// 选中的游玩日期
const checkedPriceInfo = reactive({
	date: "",
	price_in_cent: "",
	// 最近90天是否都不可售卖
	isAllNoneSellable: false,
})
const ticketData = ref({})
const tabList = ref([
	{
		id: "product-order",
		text: "产品预定",
	},
	{
		id: "buy-notice",
		text: "购买须知",
	},
	{
		id: "product-intro",
		text: "产品介绍",
	},
])
const calendarVisible = ref(false)
const commonStore = useCommonStore()

const baseTop = uni.upx2px(640) - commonStore.navbarHeight - commonStore.statusBarHeight
const instance = getCurrentInstance()

const navbarProps = computed(() => ({
	"bg-color": tabShow.value ? "#fff" : "transparent",
	title: tabShow.value ? ticketData.value.display_name : "",
}))

const hasPrices = computed(() => {
	if (ticketData.value.enabled !== 1) return false

	// 日历票
	if (ticketData.value.sale_type === 10) {
		return !checkedPriceInfo.isAllNoneSellable
	}

	// 预售票
	if (ticketData.value.sale_type === 20) {
		return ticketData.value?.prices?.[0]?.salable && !ticketData.value?.prices?.[0]?.sold_out
	}
})

const getTicketDetail = async () => {
	const data = await $getTicketDetail(id.value)

	ticketData.value = data

	if (ticketData.value.sale_type === 20) {
		checkedPriceInfo.price_in_cent = ticketData.value.prices[0].price_in_cent
	}

	nextTick(getDistanceArr)
}

const submit = () => {
	if (!hasPrices.value) return

	needLogin(() =>
		uni.navigateTo({ url: `/pages/product/ticket/submit-order?id=${id.value}&date=${checkedPriceInfo.date}` })
	)
}

const getDistanceArr = () => {
	if (ticketData.value.sale_type !== 10) {
		tabList.value = tabList.value.filter((item) => item.id !== "product-order")
	}

	tabList.value.map((el) => {
		uni.createSelectorQuery()
			.in(instance)
			.select(`#${el.id}`)
			.boundingClientRect((data) => {
				el.top = data.top - (uni.upx2px(88) + commonStore.navbarHeight + commonStore.statusBarHeight)
			})
			.exec()
	})
}

const handleTabClick = (id) => {
	if (currentTabId.value === id) return

	if (timer) clearTimeout(timer)

	isTabChange.value = true

	currentTabId.value = id

	uni.pageScrollTo({
		scrollTop: tabList.value.find((item) => item.id === currentTabId.value).top,
		complete: () => {
			timer = setTimeout(() => {
				isTabChange.value = false
				clearTimeout(timer)
			}, 500)
		},
	})
}

const handlePriceChange = (info) => {
	checkedPriceInfo.date = info.date
	checkedPriceInfo.price_in_cent = info.price_in_cent
	checkedPriceInfo.isAllNoneSellable = info.isAllNoneSellable
}

const handleCalendarVisible = (visible) => {
	calendarVisible.value = visible
}

onLoad((options) => {
	id.value = options.id

	if (options.scene) {
		const scene = decodeURIComponent(options.scene)
		id.value = getIdBYScene(scene)
	}

	getTicketDetail()
})

onPageScroll(({ scrollTop }) => {
	scroll_top = scrollTop

	// 防止调用 uni.pageScrollTo 方法使页面滚动后，onPageScroll 重复触发
	if (isTabChange.value) return

	if (scrollTop >= baseTop) {
		tabShow.value = true

		const index = tabList.value.findIndex((item) => item.top - scrollTop > 0)

		if (index === -1) {
			currentTabId.value = tabList.value[tabList.value.length - 1].id
		}

		if (index > 0) {
			currentTabId.value = tabList.value[index - 1].id
		}

		if (index === 0) {
			currentTabId.value = tabList.value[index].id
		}
	} else {
		tabShow.value = false
	}
})

onReachBottom(() => {
	if (scroll_top < tabList.value[tabList.value.length - 1].top) {
		currentTabId.value = tabList.value[tabList.value.length - 1].id

		isTabChange.value = true

		timer = setTimeout(() => {
			isTabChange.value = false
			clearTimeout(timer)
		}, 500)
	}
})
</script>

<style lang="scss" scoped>
@import "index.scss";

.page-container {
	padding-bottom: calc(128rpx + 48rpx + env(safe-area-inset-bottom));
}

.tabs {
	position: fixed;
	left: 0;
	display: flex;
	align-items: center;
	width: 100vw;
	padding: 32rpx 0 12rpx;
	background-color: #fff;
	z-index: 1000;

	.item {
		position: relative;
		flex: 1;
		font-size: 28rpx;
		color: rgba(0, 0, 0, 0.6);
		line-height: 40rpx;
		text-align: center;

		&.checked {
			font-weight: 600;
			font-size: 28rpx;
			color: rgba(0, 0, 0, 0.9);
			line-height: 44rpx;

			&::before {
				content: "";
				position: absolute;
				left: 50%;
				bottom: -6rpx;
				transform: translateX(-50%);
				width: 44rpx;
				height: 6rpx;
				background: #fee038;
				border-radius: 6rpx;
			}
		}
	}
}

.prices {
	padding-right: 32rpx;
	padding-bottom: 28rpx;
}

.resort {
	height: 192rpx;
	background-repeat: no-repeat;
	background-size: cover;
}

.bottom {
	position: fixed;
	bottom: 0;
	left: 0;
	width: 100vw;
	height: calc(128rpx + env(safe-area-inset-bottom));
	height: calc(128rpx + constant(safe-area-inset-bottom));
	padding: 24rpx 24rpx calc(24rpx + env(safe-area-inset-bottom));
	background-color: #fff;
	box-shadow: inset 0rpx 2rpx 0rpx 0rpx #f1f2f5;
	display: flex;
	align-items: center;
	justify-content: space-between;
	z-index: 10;

	.icons {
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;

		.home-icon {
			width: 40rpx;
			height: 40rpx;
			margin-bottom: 4rpx;
		}

		.text {
			font-size: 24rpx;
			color: #1d2129;
			line-height: 34rpx;
		}
	}

	.btn {
		width: 320rpx;
		height: 80rpx;
		line-height: 80rpx;
		background: #fee038;
		border-radius: 40rpx;
		font-weight: 600;
		font-size: 28rpx;
		color: #1d2129;
		text-align: center;

		&.disabled {
			background-color: #f6f6f9;
		}
	}
}
</style>
